/**
 * H5 陀螺仪插件
 * 模拟 uni-app 陀螺仪 API 在 H5 平台的实现
 */

class H5Gyroscope {
  constructor() {
    this.isListening = false;
    this.callbacks = [];
    this.interval = 200; // 默认间隔200ms
    this.lastData = null;
    this.deviceOrientationHandler = null;
    this.deviceMotionHandler = null;
  }

  /**
   * 开始监听陀螺仪数据
   * @param {Object} options 
   * @param {number} options.interval 监听陀螺仪数据回调函数的执行频率，单位 ms，默认为200ms
   * @param {Function} options.success 接口调用成功的回调函数
   * @param {Function} options.fail 接口调用失败的回调函数
   * @param {Function} options.complete 接口调用结束的回调函数
   */
  startGyroscope(options = {}) {
    const { interval = 200, success, fail, complete } = options;
    
    try {
      // 检查浏览器是否支持
      if (!window.DeviceOrientationEvent && !window.DeviceMotionEvent) {
        const error = {
          errMsg: 'startGyroscope:fail 当前浏览器不支持陀螺仪功能'
        };
        fail && fail(error);
        complete && complete(error);
        return;
      }

      // 如果已经在监听，先停止
      if (this.isListening) {
        this.stopGyroscope();
      }

      this.interval = interval;
      this.isListening = true;

      // 设置设备方向监听
      this.deviceOrientationHandler = (event) => {
        if (!this.isListening) return;
        
        const data = {
          x: event.beta || 0,   // X轴，范围[-180, 180]，表示设备在x轴上的旋转角度
          y: event.gamma || 0,  // Y轴，范围[-90, 90]，表示设备在y轴上的旋转角度  
          z: event.alpha || 0   // Z轴，范围[0, 360)，表示设备在z轴上的旋转角度
        };

        this.lastData = data;
        
        // 通知所有回调函数
        this.callbacks.forEach(callback => {
          callback(data);
        });
      };

      // 设置设备运动监听（作为备用）
      this.deviceMotionHandler = (event) => {
        if (!this.isListening || this.lastData) return;
        
        const rotationRate = event.rotationRate;
        if (rotationRate) {
          const data = {
            x: rotationRate.beta || 0,
            y: rotationRate.gamma || 0,
            z: rotationRate.alpha || 0
          };
          
          this.lastData = data;
          
          // 通知所有回调函数
          this.callbacks.forEach(callback => {
            callback(data);
          });
        }
      };

      // 请求权限（iOS 13+需要）
      if (typeof DeviceOrientationEvent !== 'undefined' && typeof DeviceOrientationEvent.requestPermission === 'function') {
        DeviceOrientationEvent.requestPermission()
          .then(permissionState => {
            if (permissionState === 'granted') {
              this.addEventListeners();
              const result = { errMsg: 'startGyroscope:ok' };
              success && success(result);
              complete && complete(result);
            } else {
              const error = { errMsg: 'startGyroscope:fail 用户拒绝了陀螺仪权限' };
              fail && fail(error);
              complete && complete(error);
            }
          })
          .catch(error => {
            const err = { errMsg: 'startGyroscope:fail ' + error.message };
            fail && fail(err);
            complete && complete(err);
          });
      } else {
        // 直接添加监听器
        this.addEventListeners();
        const result = { errMsg: 'startGyroscope:ok' };
        success && success(result);
        complete && complete(result);
      }

    } catch (error) {
      const err = { errMsg: 'startGyroscope:fail ' + error.message };
      fail && fail(err);
      complete && complete(err);
    }
  }

  /**
   * 添加事件监听器
   */
  addEventListeners() {
    window.addEventListener('deviceorientation', this.deviceOrientationHandler, true);
    window.addEventListener('devicemotion', this.deviceMotionHandler, true);
  }

  /**
   * 停止监听陀螺仪数据
   * @param {Object} options
   * @param {Function} options.success 接口调用成功的回调函数
   * @param {Function} options.fail 接口调用失败的回调函数
   * @param {Function} options.complete 接口调用结束的回调函数
   */
  stopGyroscope(options = {}) {
    const { success, fail, complete } = options;
    
    try {
      this.isListening = false;
      
      // 移除事件监听器
      if (this.deviceOrientationHandler) {
        window.removeEventListener('deviceorientation', this.deviceOrientationHandler, true);
      }
      if (this.deviceMotionHandler) {
        window.removeEventListener('devicemotion', this.deviceMotionHandler, true);
      }
      
      this.lastData = null;
      
      const result = { errMsg: 'stopGyroscope:ok' };
      success && success(result);
      complete && complete(result);
      
    } catch (error) {
      const err = { errMsg: 'stopGyroscope:fail ' + error.message };
      fail && fail(err);
      complete && complete(err);
    }
  }

  /**
   * 监听陀螺仪数据变化事件
   * @param {Function} callback 陀螺仪数据变化事件的回调函数
   */
  onGyroscopeChange(callback) {
    if (typeof callback === 'function') {
      this.callbacks.push(callback);
    }
  }

  /**
   * 取消监听陀螺仪数据变化事件
   * @param {Function} callback 要取消的回调函数，如果不传则取消所有回调
   */
  offGyroscopeChange(callback) {
    if (callback) {
      const index = this.callbacks.indexOf(callback);
      if (index > -1) {
        this.callbacks.splice(index, 1);
      }
    } else {
      this.callbacks = [];
    }
  }

  /**
   * 获取当前陀螺仪状态
   */
  getGyroscopeStatus() {
    return {
      isListening: this.isListening,
      interval: this.interval,
      lastData: this.lastData,
      callbackCount: this.callbacks.length
    };
  }
}

// 创建插件实例
const h5Gyroscope = new H5Gyroscope();

// 导出插件方法
export default {
  /**
   * 开始监听陀螺仪数据
   */
  startGyroscope: (options) => h5Gyroscope.startGyroscope(options),
  
  /**
   * 停止监听陀螺仪数据
   */
  stopGyroscope: (options) => h5Gyroscope.stopGyroscope(options),
  
  /**
   * 监听陀螺仪数据变化事件
   */
  onGyroscopeChange: (callback) => h5Gyroscope.onGyroscopeChange(callback),
  
  /**
   * 取消监听陀螺仪数据变化事件
   */
  offGyroscopeChange: (callback) => h5Gyroscope.offGyroscopeChange(callback),
  
  /**
   * 获取当前陀螺仪状态
   */
  getGyroscopeStatus: () => h5Gyroscope.getGyroscopeStatus()
};
